
package cn.e3mall.common.utils;

import com.alibaba.fastjson.*;
import com.google.gson.*;
import org.apache.http.HttpStatus;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/**
 * Created by taylor on 8/7/16.
 * twitter: @taylorwang789
 */
public class ValueUtil {

    public static String defaultSuccess = "success";

    public static boolean notEmpity(Object obj) {
        if (null == obj) {
            return false;
        } else if (obj.toString().equals("")) {
            return false;
        } else {
            return true;
        }
    }

    public static boolean isEmpity(Object obj) {
        return !notEmpity(obj);
    }


    public static <T> T coalesce(T... args) {
        for (int i = 0; i < args.length; i++) {
            if (notEmpity(args[i])) {
                return args[i];
            }
        }
        return (T) "";
    }

    public static Gson gsonExp = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();
    //    public static Gson gson = new Gson();
    public static Gson gson = new GsonBuilder().serializeNulls().create();

//    public static String toJson(String code, Object obj) {
//        RestJson restJson = new RestJson();
////        restJson.setCode(code);
//        restJson.setMsg(defaultSuccess);
//        restJson.setData(coalesce(obj, ""));
//        return gson.toJson(restJson);
//    }

    public static String toJson(Integer code, Object obj) {
        RestJson restJson = new RestJson();
        restJson.setCode(String.valueOf(code));
        restJson.setMsg(defaultSuccess);
        restJson.setData(coalesce(obj, ""));
        return gson.toJson(restJson);
    }

    public static String toJson(Integer code, String msg,Object obj ) {
        RestJson restJson = new RestJson();
        restJson.setCode(String.valueOf(code));
        restJson.setMsg(msg);
        restJson.setData(coalesce(obj, ""));
        return gson.toJson(restJson);
    }

    public static String toJson(Object obj) {
        try {
            RestJson restJson = new RestJson();
            restJson.setCode(String.valueOf(HttpStatus.SC_OK));
            restJson.setMsg(defaultSuccess);
            restJson.setData(coalesce(obj, ""));
//            JSONValue jsonValue = JSONMapper.toJSON(restJson);
//            String jsonStr = jsonValue.render(false);
//            return jsonStr;
            return gson.toJson(restJson);
        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }

    public static JSONObject toJsonObject(Object obj) {
        try {
            return JSON.parseObject(gson.toJson(coalesce(obj, ""))) ;
        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }


    public static String toString(Object obj) {
        return gson.toJson(obj);
    }


    public static String toJson(Object... objs) {
        RestJson restJson = toRestJson(objs);
        return gson.toJson(restJson);
    }

    public static String toJsonExp(Object... objs) {
        RestJson restJson = toRestJson(objs);
        return gsonExp.toJson(restJson);
    }


    public static String toError(String code, String message) {
        RestJson restJson = new RestJson();
        restJson.setCode(code);
        restJson.setData("");
        restJson.setMsg(message);
        return toString(restJson);
    }

    public static String toError(String code, String message, Object object) {
        RestJson restJson = toRestJson(object);
        restJson.setCode(code);
        restJson.setData(object);
        restJson.setMsg(message);
        return gson.toJson(restJson);
    }

    public static String toError(Integer code, String message) {
        RestJson restJson = new RestJson();
        restJson.setCode(String.valueOf(code));
        restJson.setMsg(message);
        restJson.setData("");
        return toString(restJson);
    }

    public static RestJson toRestJson(Object... objs) {
        RestJson restJson = new RestJson();
        restJson.setCode(String.valueOf(HttpStatus.SC_OK));
        restJson.setMsg("");
        Map<String, Object> map = new HashMap<>();
        boolean isOdd = true;
        String key = "";
        for (int i = 0; i < objs.length; i++) {
            if (isOdd) {
                key = objs[i].toString();
                isOdd = false;
            } else {
                if (notEmpity(objs[i])) {
                    map.put(key, objs[i]);
                } else {
                    map.put(key, new JsonObject());
                }
                isOdd = true;
            }
        }
        restJson.setData(map);
        return restJson;
    }


    private static JsonParser jsonParser = new JsonParser();

    public static JsonElement getFromJson(String json) {
        JsonElement origin = jsonParser.parse(json);
        return origin;
    }

    public static <T> T getFromJson(String json, Class<T> clz) {
        return gson.fromJson(json, clz);
    }

    public static String getFromJson(String json, Object... args) {
        JsonObject origin = jsonParser.parse(json).getAsJsonObject();
        for (int i = 0; i < args.length; i++) {
            if ((i + 1) == args.length) {
                String returnString = origin.get(args[i].toString()).toString();
                if (returnString.startsWith("\"")) {
                    return returnString.substring(1, returnString.length() - 1);
                } else {
                    return returnString;
                }
            } else {
                if (args[i].getClass().equals(Integer.class)) {
                    origin = origin.getAsJsonArray().get(Integer.valueOf(args[i].toString())).getAsJsonObject();
                }
                if (args[i].getClass().equals(String.class)) {
                    origin = origin.getAsJsonObject(args[i].toString());
                }
            }
        }
        return origin.toString();
    }

    public static void verify(boolean wanna, boolean condition, String errorCode) throws Exception {
        if (isEmpity(condition)) {
            throw new Exception(errorCode);
        } else {
            if (wanna != condition) {
                throw new Exception(errorCode);
            }
        }
    }

    public static Map Objcet2Map(Object obj) throws Exception {
        Map map = new HashMap<String, Object>();
        Class clazz = obj.getClass();
//获取所有属性
        Field[] fields = clazz.getDeclaredFields();
//迭代属性数组
        for (Field field : fields) {
//获取属性名
            String name =field.getName();
//拼接get方法名
            String methodName = "get"+name.substring(0,1).toUpperCase()+name.substring(1,name.length());
//获取方法
            Method method = clazz.getDeclaredMethod(methodName);
//执行方法
            Object value = method.invoke(obj);
            map.put(name, value);
        }
        return map;
    }

    /**
     * 把一个map集合转化为目标对象
     * @param clazz 目标对象的字节码对象
     * @param map  map集合
     * @return  字节码对象生产的目标对象
     */
    public static Object map2Object(Class clazz,Map map) throws Exception {
//构造迭代器
        Iterator iterator = map.entrySet().iterator();
//根据字节码生产对象
        Object obj = clazz.newInstance();
//迭代map集合
        while (iterator.hasNext()) {
//Entry <K,V>
            Map.Entry e = (Map.Entry) iterator.next();
//获取Key 和 Value
            String key = (String) e.getKey();
            Object value = e.getValue();
//根据属性名称获取属性
            Field field = clazz.getDeclaredField( key );

//拼接set方法名     因为  field.set(obj, value)方法不允许修改private 的属性
            String methodName = "set" + key.substring( 0, 1 ).toUpperCase() + key.substring( 1, key.length() );
//根据方法名称和参数类型获取方法
            Method method = clazz.getDeclaredMethod( methodName, field.getType() );
//执行方法
            method.invoke( obj, value );
        }
    return obj;
    }

}

